﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Caching;
using blackhouse.AsyncMail.Business;
using blackhouse.AsyncMail.Business.Data;
using System.Configuration;
using System.Net;
using System.IO;
using System.Net.Mail;

namespace blackhouse.AsyncMail.Web {
	public class CacheTaskRunner {

		#region Fields

		private const string CACHE_KEY = "ASyncMail";

		#endregion

		#region Methods

		public static void RunTaskerOnCache() {
			object asyncmail = HttpContext.Current.Cache[CACHE_KEY];
			if (asyncmail == null) {
				AddCache(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority));
			}
		}

		public static void RerunTaskerOnCache(string key, object value, CacheItemRemovedReason reason) {
			RunTask(value.ToString());
			AddCache(value.ToString());
		}

		private static void RunTask(string host) {
			ASyncMail mail = new ASyncMail(new SqlASyncMailDataAccess(GetConnectionString()));
			if (mail.FillByTop()) {
				SendMail(mail, host);
			}
		}

		private static void SendMail(ASyncMail mail, string host) {
			string url = host + "/" + ASyncHtmlMailGenerator.GetMailDirectory() + "/ASyncHtmlMailGenerator.aspx?requestId=" + mail.RequestId;
			WebRequest request = HttpWebRequest.Create(url);
			WebResponse response = request.GetResponse();
			string mailToSend = "";
			using (Stream stream = response.GetResponseStream())
			using (StreamReader sr = new StreamReader(stream)) {
				mailToSend = sr.ReadToEnd();
			}
			MailMessage mailMessage = new MailMessage();
			SmtpClient client = new SmtpClient();
			if (client.Port == 587)
				client.EnableSsl = true;
			mailMessage.Subject = mail.MessageTitle;
			mailMessage.Body = mailToSend;
			mailMessage.IsBodyHtml = true;
			mailMessage.To.Add(mail.Receiver);
			client.Send(mailMessage);
			mail.MarkAsSended();
		}

		private static void AddCache(string value) {
			HttpContext.Current.Cache.Add(CACHE_KEY,
				value,
				null,
				DateTime.Now + TimeSpan.FromSeconds(GetCacheInterval()),
			System.Web.Caching.Cache.NoSlidingExpiration,
			System.Web.Caching.CacheItemPriority.AboveNormal,
			new System.Web.Caching.CacheItemRemovedCallback(RerunTaskerOnCache));
		}

		internal static string GetAppHost() {
			object path = HttpContext.Current.Cache[CACHE_KEY];
			if (path == null)
				return "";
			else
				return path.ToString();
		}

		internal static string GetConnectionString() {
			return ConfigurationManager.AppSettings["MSSQLConnectionString"];
		}

		private static int GetCacheInterval() {
			string sInt = ConfigurationManager.AppSettings["CacheInterval"];
			if (!string.IsNullOrEmpty(sInt)) {
				int iInt = 0;
				if (Int32.TryParse(sInt, out iInt))
					return iInt;
			}
			return 30;
		}

		#endregion

	}
}